package com.googlecode.cnasort.cc.rmi.server.core;

import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.HashMap;
import org.apache.log4j.Logger;
import com.googlecode.cnasort.cc.rmi.common.RMIFileLoaderConnector;
import com.googlecode.cnasort.cc.rmi.common.data.RMIDirectory;
import com.googlecode.cnasort.cc.rmi.common.data.RMIFile;
import com.googlecode.cnasort.cc.rmi.common.data.RMIFileLoader;
import com.googlecode.cnasort.cc.rmi.common.data.RMIFileLoaderId;

/**
 * Default implementation of {@link RMIFileLoaderConnector}
 */
public class RMIFileLoaderConnectorImpl implements RMIFileLoaderConnector, Serializable
{
    private static final long serialVersionUID = -695385617089249605L;
    private static final Logger logger = Logger.getLogger( RMIFileLoaderConnectorImpl.class );

    private HashMap<RMIFileLoaderId,RMIFileLoader> connectionMap = new HashMap<>();
    private String serviceName;

    protected RMIFileLoaderConnectorImpl() throws RemoteException
    {
    }

    public static Remote createRemote( String serviceName ) throws RemoteException
    {
        RMIFileLoaderConnectorImpl instance = new RMIFileLoaderConnectorImpl();

        instance.serviceName = serviceName;

        return instance;
    }

    @Override
    public boolean connect( final RMIFileLoaderId id ) throws RemoteException
    {
        logger.info( "[S] received connect()" );
       // TODO checkid

        RMIFileLoader fileLoader = new RMIFileLoaderImpl( id );

        this.connectionMap.put( id, fileLoader );

        return true;
    }

    private RMIFileLoader getConnection( final RMIFileLoaderId id )
        throws RemoteException
    {
        RMIFileLoader fileLoader = this.connectionMap.get( id );

        if( fileLoader == null ) {
            throw new RemoteException( "Not connected" );
            }
        else {
            return fileLoader;
            }
    }

    @Override
    public void disconnect( final RMIFileLoaderId id ) throws RemoteException
    {
        RMIFileLoader fileLoader = getConnection( id );

        try {
            fileLoader.closeFileTransfert();
            }
        finally {
            this.connectionMap.remove( id );
        }
    }


    @Override
    public RMIDirectory[] getRootDirectories( final RMIFileLoaderId id )
        throws RemoteException
    {
        logger.info( "[S] received getRootDirectories()" );

        return getConnection( id ).getRootDirectories();
    }

    @Override
    public RMIDirectory[] getDirectories(
        final RMIFileLoaderId id,
        final RMIDirectory    directory
        ) throws RemoteException
    {
        return getConnection( id ).getDirectories( directory );
    }

    @Override
    public RMIFile[] getFiles(
        final RMIFileLoaderId id,
        final RMIDirectory    directory
        ) throws RemoteException
    {
        return getConnection( id ).getFiles( directory );
    }

//    @Override
//    public byte[] getFileContent(
//        final RMIFileLoaderId id,
//        final RMIFile         file
//        ) throws RemoteException
//    {
//        return getConnection( id).getFileContent( file );
//    }

    @Override
    public void setFileTransfertBufferSize(
        final RMIFileLoaderId   id,
        final int               maxBufferSize
        ) throws RemoteException
    {
        getConnection( id ).setFileTransfertBufferSize( maxBufferSize );
    }

    @Override
    public int getFileTransfertBufferSize( final RMIFileLoaderId id )
        throws RemoteException
    {
        return getConnection( id ).getFileTransfertBufferSize();
    }

    @Override
    public void openFileTransfert(
        final RMIFileLoaderId id,
        final RMIFile         file
        ) throws RemoteException
    {
        getConnection( id ).openFileTransfert( file );
    }

    @Override
    public boolean isFileTransfertComplete( final RMIFileLoaderId id )
        throws RemoteException
    {
        return getConnection( id ).isFileTransfertComplete();
    }

    @Override
    public byte[] nextFileTransfertPart( final RMIFileLoaderId id )
        throws RemoteException
    {
        return getConnection( id ).nextFileTransfertPart();
    }

    @Override
    public void closeFileTransfert( final RMIFileLoaderId id )
        throws RemoteException
    {
        getConnection( id ).closeFileTransfert();
    }

    @Override
    public void quit() throws RemoteException
    {
        logger.info( "received quit()" );

        RMIFileLoaderConnectorHelper.quit( this, this.serviceName );
    }
}
